<?php
SPRPC_Core::import('SPRPC_Exception_Client');
SPRPC_Core::import('SPRPC_Handler_Base');
/**
 * xmlrpc client
 * make calls to remote and
 * parse response
 * @uses SPRPC_Handler_Base
 * @author bbqq
 * @copyright 2010 qstufie.com
 * @package com.sprpc.handler
 */
class SPRPC_Handler_Client extends SPRPC_Handler_Base
{
    /**
     * the poster
     * @var SPRPC_Utility_HttpRequest
     */
    protected $_remote = null;


    /**
     * needs url and token to make calls...
     * @param $url the url to call
     * @param $token the token
     * @return void
     */
    public function __construct($url = null, $token = null)
    {
        // get token and urls...
        // as you can see, these can be null, so default is from config...
        if (empty($url)) {
            $url = (string) SPRPC_Utility_Config::get('url');
            if (empty($url)) {
                // empty again?
                throw new exception('URL is empty', 1);
            }
        }

        if (empty($token)) {
            $token = (string) SPRPC_Utility_Config::get('token');
            if (empty($token)) {
                // empty again?
                throw new exception('token is empty', 1);
            }
        }

        // timeout, default 5 minutes
        $timeout = (int) SPRPC_Utility_Config::get('timeout', 300);
        $this->_remote = new SPRPC_Utility_HttpRequest($url, 'POST', $timeout);
        $this->_token  = $token;

    }// end __construct


    /**
     * take method calls
     * call remote
     * @param $method the method to call
     * @param $args the params
     * @return mixed the actual class call results in proper array or object form
     */
    public function __call($method, $args = array())
    {
        // first, compose the call...
        $payload = array(
            'method' => $method,
            'args'   => $args
        );

        // set up
        $request = $this->_compose('request', $payload);

        // call and return...
        $this->_remote->setQueryData($request);
        $resp = $this->_remote->send();

        // let's see what's returned...
        if (!empty($resp)) {
            // first, validate if error...
            if (strpos($resp, '<error>') !== false && strpos($resp, '</error>') !== false) {
                // error!
                return $this->_parseError($resp);
            }

            // try putting something nice there...
            $this->_parse($resp);
            // validate...
            if ($this->_mkchecksum($this->_payload, $this->_token) !== $this->_checksum) {
                throw new SPRPC_Exception_Client('DATA INTEGRITY CHECK FAILURE', 3, $request, $resp);
            }
            // otherwise, all good...
            return unserialize(base64_decode($this->_payload));
        }

        throw new SPRPC_Exception_Client('RESPONSE IS EMPTY', 3, $request);

    }// end __call

} // end SPRPC_Handler_Client
?>